# TODO: Add comment
# 
# Author: rogb
###############################################################################


setClass("OptionPortfolio",
		contains=c(
				"list"
		)
)

OptionPortfolio <- function(...){
	new("OptionPortfolio",list(...))	
}

if(F){
	o1 <- GBSOption("p","SX5E",1,100,DateYMD(2009,12,31),DateYMD(2010,12,31),"EUR","SX5E Option","EUREX")
	o2 <- GBSOption("p","SX5E",-1,55,DateYMD(2009,12,31),DateYMD(2010,12,31),"EUR","SX5E Option","EUREX")
	o3 <- GBSOption("p","SX5E",-1,115,DateYMD(2009,12,31),DateYMD(2010,12,31),"EUR","SX5E Option","EUREX")
	
	o4 <- GBSOption("p","SPX",1,100,DateYMD(2009,12,31),DateYMD(2010,12,31),"USD","SPX Option","EUREX")
	o5 <- GBSOption("p","SPX",-1,55,DateYMD(2009,12,31),DateYMD(2010,12,31),"USD","SPX Option","EUREX")
	o6 <- GBSOption("p","SPX",-1,115,DateYMD(2009,12,31),DateYMD(2010,12,31),"USD","SPX Option","EUREX")
	
	o7 <- GBSOption("c","SX5E",1,90,DateYMD(2009,12,31),DateYMD(2010,12,31),"EUR","SX5E Option","EUREX")
	o8 <- GBSOption("c","SPX",1,90,DateYMD(2009,12,31),DateYMD(2010,12,31),"USD","SPX Option","EUREX")
	
	
	impliedVolatility(o1) <- 20.961
	impliedVolatility(o2) <- 20.961
	impliedVolatility(o3) <- 20.961
	impliedVolatility(o4) <- 21.68
	impliedVolatility(o5) <- 21.68
	impliedVolatility(o6) <- 21.68
	
	impliedVolatility(o7) <- 20.961
	impliedVolatility(o8) <- 21.68
	
	riskFreeRate(o1) <- 1.5
	riskFreeRate(o2) <- 1.5
	riskFreeRate(o3) <- 1.5
	riskFreeRate(o4) <- 1.5
	riskFreeRate(o5) <- 1.5
	riskFreeRate(o6) <- 1.5
	riskFreeRate(o7) <- 1.5
	riskFreeRate(o8) <- 1.5
	costOfCarryRate(o1) <- 0
 	costOfCarryRate(o2) <- 0
	costOfCarryRate(o3) <- 0
	costOfCarryRate(o4) <- 0
	costOfCarryRate(o5) <- 0
	costOfCarryRate(o6) <- 0
	costOfCarryRate(o7) <- 0
	costOfCarryRate(o8) <- 0
	price(o1) <-  7.5615342
	price(o2) <- 0.2227984
	price(o3) <- 15.3183057
	
	price(o4) <- 7.8439173
	price(o5) <- 0.2726599
	price(o6) <- 15.4866439
	
	price(o7) <- 13.69902
	price(o8) <- 13.93492
	
	
	spx <- OptionPortfolio(o4,o5,o6)
	sx5e <- OptionPortfolio(o1,o2,o3)
	
	
	x <- OptionPortfolio(o1,o2,o3)
	x <- OptionPortfolio(o1,o2,o3,o4,o5)
	
	on1 <- GBSOption("c","NOVN",100,56,Sys.Date(),DateYMD(2010,6,18),"CHF","Novn Option","EUREX")
	on2 <- GBSOption("c","NOVN",-100,60,Sys.Date(),DateYMD(2010,6,18),"CHF","Novn Option","EUREX")
	costOfCarryRate(on1) <- 0
	costOfCarryRate(on2) <- 0
	riskFreeRate(on1) <- 0.5
	riskFreeRate(on2) <- 0.5
	price(on1) <- 0.92
	price(on2) <- 0.17
	impliedVolatility(on1) <- calculateImpliedVolatility(on1,54.85)
	impliedVolatility(on2) <- calculateImpliedVolatility(on2,54.85)
	
	pp <- OptionPortfolio(on1,on2)
}
# 
#x <- x[-3]
#class(x) <- "OptionPortfolio"
#sapply(sx5e,presentValue,100)
#sapply(x,calculateImpliedVolatility,6550)

setMethod("plot",signature="OptionPortfolio",function(x,y,...){
			dotdotdot <- list(...)		
			
			nOption <- length(x)
			
			tmpStrike <- sort(sapply(x,strike))
			tmpStrike2 <- c(min(tmpStrike)*0.8,tmpStrike,max(tmpStrike)*1.2)
			strikeRange <- max(tmpStrike2) - min(tmpStrike2)
			tmpStrike3 <- cbind(tmpStrike2[1:(length(tmpStrike2)-1)],tmpStrike2[2:length(tmpStrike2)])
			tmpStrike4 <- apply(tmpStrike3,1,function(x){
						seq(x[1],x[2],length.out=max(20,nOption*2)*(x[2]-x[1])/strikeRange)
					})
			UnderlyingValue <- sort(unique(unlist(tmpStrike4)))
			
			nUnderlyingValue <- length(UnderlyingValue)
			minMaturity <- as.Date(min(sapply(x,maturityDate),na.rm=T),origin="1970-01-01")
			
			CalcDate <- seq(situationDate(x[[1]]),minMaturity,length.out=4)
			nCalcDate <- length(CalcDate)
			
			
			optionPrice <- sapply(x,price)
			ScenCalc <- array(NA,c(nUnderlyingValue,nCalcDate,nOption))
			for(i in 1:nOption){
				# i <- 1
				ScenCalc[,,i] <- sapply(1:nCalcDate,function(i,x){
							situationDate(x) <- CalcDate[i]
							sapply(UnderlyingValue,function(uv,object)presentValue(object,uv),x)
						},x[[i]])-optionPrice[[i]] * quantity(x[[i]])
			}
			
			SumScenCalc <- apply(ScenCalc,c(1,2),sum)
			ylim <- range(c(ScenCalc,SumScenCalc))
			plot(UnderlyingValue,SumScenCalc[,nCalcDate],type="l",lwd=3,main="PLOT",ylab="Final Pay Out",xlab=underlying(x[[1]]),ylim=ylim)
			abline(h=0)
			for(i in (nCalcDate-1):1)
				lines(UnderlyingValue,SumScenCalc[,i],lwd=3,col=i+1)
			
			for(o in 1:nOption){
				if(length(dotdotdot$plotAllOptions)>0 && dotdotdot$plotAllOptions==TRUE){
					for(i in 1:(nCalcDate)){
						col <- i + 1
						col[i==nCalcDate] <- 1
						lines(UnderlyingValue,ScenCalc[,i,o],lwd=1,col=col,lty=o)
					}
				}	
				abline(v=strike(x[[o]]),lty=2)
			}
					
			legend("bottomleft",as.character(CalcDate),col=c(2:(nCalcDate),1),lwd=c(rep(2,nCalcDate),3))
			
})
			
setMethod("[",signature=c("OptionPortfolio","numeric","missing"),function(x,i,j,drop){			
			tmp <- x
			tmp[-i] <- NULL
			tmp
		})

setMethod("presentValue",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,presentValue,arg1))
		})

setMethod("delta",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,delta,arg1))
		})

setMethod("gammma",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,gammma,arg1))
		})

setMethod("deltagamma01",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,deltagamma01,arg1))
		})

setMethod("deltagamma01empirical",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,deltagamma01empirical,arg1))
		})

setMethod("theta",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,theta,arg1))
		})

setMethod("vega",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,vega,arg1))
		})

setMethod("vomma",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,vomma,arg1))
		})

setMethod("vegavomma01",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,vegavomma01,arg1))
		})

setMethod("vegavomma01empirical",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,vegavomma01empirical,arg1))
		})

setMethod("rho",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,rho,arg1))
		})

setMethod("rho2",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,rho2,arg1))
		})

setMethod("dv01",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,dv01,arg1))
		})

setMethod("dv01empirical",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,dv01empirical,arg1))
		})

setMethod("rhoCoC",signature=c("OptionPortfolio","numeric"),function(object,arg1){
			sum(sapply(object,rhoCoC,arg1))
		})

calculateVolatilitySurface <- function(InputOptionPortfolio){
	
}


